/**
 * 
 */
package com.wgo.bpot.server.configuration.impl;

import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.log4j.Logger;

import com.wgo.bpot.domain.common.User;
import com.wgo.bpot.domain.common.impl.UserImpl;
import com.wgo.bpot.server.bpot_users.UserType;
import com.wgo.bpot.server.bpot_users.Users;
import com.wgo.bpot.server.configuration.UsersFileServices;
import com.wgo.bpot.server.configuration.exception.InvalidUserRoleException;

/**
 * @author peide3
 * @version $Id: UsersFileServicesImpl.java 540 2008-01-09 19:42:31Z petter.eide $
 */
public abstract class UsersFileServicesImpl implements UsersFileServices {

	private static final transient Logger log = Logger.getLogger(UsersFileServicesImpl.class);

	public static final String USERFILE_NAME="/bpot-users.xml";
	private final JAXBContext context ;
	private final Unmarshaller unmarshaller;

	public UsersFileServicesImpl(){
		JAXBContext initContext = null;
		try {
			initContext = JAXBContext.newInstance("com.wgo.bpot.server.bpot_users");
		} catch (JAXBException e) {
			log.error("Unable to instantiate JAXBContext", e);
		} finally {
			context = initContext;
		}
		Unmarshaller initUnmarshaller = null ;
		try {
			initUnmarshaller = context.createUnmarshaller();
		} catch (JAXBException e) {
			log.error("Unable to create Unmarshaller", e);
		} finally {
			unmarshaller = initUnmarshaller;
		}
	}

	/* (non-Javadoc)
	 * @see com.wgo.bpot.server.configuration.UsersFile#getUsersFromFile()
	 */
	public Set<User> getUsersFromFile() {
		return getUsersFromFileQuiet(USERFILE_NAME);
	}
	
	public Set<User> getUsersFromFileQuiet(String filename) {
		try {
			return getUsersFromFile(filename);
		} catch (JAXBException e) {
			log.warn("Unable to parse xml from file " + filename, e);
		} catch (IllegalArgumentException e) {
			log.warn(e.getMessage());
		}
		return new HashSet<User>(0);
	}

	@SuppressWarnings("unchecked")
	public Set<User> getUsersFromFile(String filename) throws JAXBException {
		getClass().getResource(filename);
		InputStream inputStream = getClass().getResourceAsStream(filename);
		if (null == inputStream){
			throw new IllegalArgumentException("Unable to open stream from file: " + filename);
		}
		Users jaxMeUsers = (Users)unmarshaller.unmarshal(inputStream);
		int numUsersReadFromFile = 0;
		Set<User> users = new HashSet<User>();
		for ( UserType userType : jaxMeUsers.getUser()) {
			try {
				users.add(createUserFromUserType(userType));
				numUsersReadFromFile++;
			} catch (InvalidUserRoleException iure ) {
				log.warn("Unable to create user: " + iure.getMessage());
			} catch (Exception e) {
				log.warn("Unable to create user: ", e);
			}
		}
		log.info("Read " + numUsersReadFromFile + " users sucessfully from file: " + filename);
		return users;
	}
	
	protected User createUserFromUserType(UserType userType) {
		User user = createNewUser();
		user.setFirstName(userType.getFirstName());
		user.setLastName(userType.getLastName());
		user.setUserName(userType.getUsername());
		user.setPassword(userType.getPassword());
		setUserRole(user, userType.getRole());
		return user;
	}
	
	protected abstract void setUserRole(User user, int userRole) throws InvalidUserRoleException;

	protected User createNewUser() {
		return new UserImpl();
	}
	/* (non-Javadoc)
	 * @see com.wgo.bpot.server.configuration.UsersFile#writeUsersToFile(java.util.Set)
	 */
	public boolean writeUsersToFile(Set<User> users) {
		// TODO Auto-generated method stub
		return false;
	}

}
